#include "Job.h"
#include <unistd.h>
#include <cstdlib>
#include <iostream>
Job :: Job(std::string line,std::string cwd)
: pid(0)
{
	char * temp;
	this->cmd = line.substr(0,line.find_first_of(" "));
	temp = realpath(cwd.c_str(),0);
	this->cwd = temp;
	free(temp);
	if(line.find_first_of(" ") != std::string::npos)
		this->args = line.substr(line.find_first_of(" "));
	ref_counter = 1;
	for ( int ios = 0 ; ios < 3 ; ios++ )
		pipe(iostreams[ios]);
	JobMan.addJob(this);
}

std::string Job :: getCWD()
{
	return cwd;
}
std::string Job :: getCMD()
{
	return cmd;
}
std::string Job :: getARGS()
{
	return args;
}


void Job :: run(bool wait)
{
	switch(pid=fork())
	{
		case 0:
		{	//Child
			std::cerr << "Command: " << cmd << " Args: " << args;
			return ;
		}
		break;
		case -1:
			//Fail
			break;
		default:
			break;
	}
	std::cerr << "Hello Parent!\n";
	if(pid != -1)
	{
		if(wait)
		{

		}
	}
}

void Job :: aquire()
{
	__sync_add_and_fetch(&ref_counter,1);
}

bool Job :: release()
{
	if(__sync_sub_and_fetch(&ref_counter,1) == 0)
	{
		delete this;
		return true;
	}
	return false;
}

Job :: ~Job()
{
	std::cerr << "Job(" << cmd << ") deleted!\n";
	JobMan.delJob(this);
}

class JobManager JobMan;


JobManager :: JobManager()
{
	sem_init(&job_sem,1,1);	//Shared,and 1 allowed
}

int JobManager :: addJob(Job * job)
{
	int inserted = 0;
	if(job)
	{
		sem_wait(&job_sem);
		inserted = jobs.insert(job).second;
		sem_post(&job_sem);
	}
	return inserted;
}
int JobManager :: delJob(Job * job)
{
	int erased = 0;
	if(job)
	{
		sem_wait(&job_sem);
		erased = jobs.erase(job);
		sem_post(&job_sem);
	}
	return erased;
}

JobManager :: ~JobManager()
{
	Job * job;
	sem_wait(&job_sem);
	while( ! jobs.empty() )
	{
		job = *jobs.begin();
		jobs.erase(job);
		if(!job->release())
			std::cerr << "Job(" << job->getCMD() << " " << job->getARGS() << "(from \"" << job->getCWD() << "\") not released!" << std::endl;
	}
//	jobs.clear();
	sem_post(&job_sem);
}
